<?xml version="1.0" encoding="utf-8"?>
<!--
                                                                                     
 h       t     t                ::       /     /                     t             / 
 h       t     t                ::      //    //                     t            // 
 h     ttttt ttttt ppppp sssss         //    //  y   y       sssss ttttt         //  
 hhhh    t     t   p   p s            //    //   y   y       s       t          //   
 h  hh   t     t   ppppp sssss       //    //    yyyyy       sssss   t         //    
 h   h   t     t   p         s  ::   /     /         y  ..       s   t    ..   /     
 h   h   t     t   p     sssss  ::   /     /     yyyyy  ..   sssss   t    ..   /     
                                                                                     
	<https://y.st./>
	Copyright © 2017 Alex Yst <mailto:copyright@y.st>

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <https://www.gnu.org./licenses/>.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<base href="https://y.st./en/coursework/CS1103/Unit7.java.xhtml" />
		<title>Unit7.java &lt;https://y.st./en/coursework/CS1103/Unit7.java.xhtml&gt;</title>
		<link rel="icon" type="image/png" href="/link/CC_BY-SA_4.0/y.st./icon.png" />
		<link rel="stylesheet" type="text/css" href="/link/basic.css" />
		<link rel="stylesheet" type="text/css" href="/link/site-specific.css" />
		<script type="text/javascript" src="/script/javascript.js" />
		<meta name="viewport" content="width=device-width" />
	</head>
	<body>
		<nav>
			<p>
				<a href="/en/">Home</a> |
				<a href="/en/a/about.xhtml">About</a> |
				<a href="/en/a/contact.xhtml">Contact</a> |
				<a href="/a/canary.txt">Canary</a> |
				<a href="/en/URI_research/"><abbr title="Uniform Resource Identifier">URI</abbr> research</a> |
				<a href="/en/opinion/">Opinions</a> |
				<a href="/en/coursework/">Coursework</a> |
				<a href="/en/law/">Law</a> |
				<a href="/en/a/links.xhtml">Links</a> |
				<a href="/en/coursework/CS1103/Unit7.java.xhtml.asc">{this page}.asc</a>
			</p>
			<hr/>
			<p>
				<a href="/en/coursework/BUS1101/" title="Principles of Business Management">BUS 1101</a> |
				<span class="hyperlink_unavailable" title="Basic Accounting">BUS 1102</span> |
				<span class="hyperlink_unavailable" title="Principles of Marketing">BUS 2201</span> |
				<span class="hyperlink_unavailable" title="Multinational Management">BUS 2207</span> |
				<span class="hyperlink_unavailable" title="Business and Society">BUS 3306</span> |
				<a href="/en/coursework/CS1101/" title="Programming Fundamentals">CS 1101</a> |
				<a href="/en/coursework/CS1102/" title="Programming 1">CS 1102</a> |
				<a href="/en/coursework/CS1103/" title="Programming 2">CS 1103</a> |
				<span class="hyperlink_unavailable" title="Computer Systems">CS 1104</span> |
				<a href="/en/coursework/CS2203/" title="Databases 1">CS 2203</a> |
				<span class="hyperlink_unavailable" title="Communications and Networking">CS 2204</span> |
				<a href="/en/coursework/CS2205/" title="Web Programming 1">CS 2205</a> |
				<a href="/en/coursework/CS2301/" title="Operating Systems 1">CS 2301</a> |
				<span class="hyperlink_unavailable" title="Software Engineering 1">CS 2401</span> |
				<span class="hyperlink_unavailable" title="Data Structures">CS 3303</span> |
				<span class="hyperlink_unavailable" title="Analysis of Algorithms">CS 3304</span> |
				<span class="hyperlink_unavailable" title="Web Programming 2">CS 3305</span> |
				<span class="hyperlink_unavailable" title="Databases 2">CS 3306</span> |
				<span class="hyperlink_unavailable" title="Operating Systems 2">CS 3307</span> |
				<span class="hyperlink_unavailable" title="Information Retrieval">CS 3308</span> |
				<span class="hyperlink_unavailable" title="Comparative Programming Languages">CS 4402</span> |
				<span class="hyperlink_unavailable" title="Software Engineering 2">CS 4403</span> |
				<span class="hyperlink_unavailable" title="Advanced Networking and Data Security">CS 4404</span> |
				<span class="hyperlink_unavailable" title="Mobile Applications">CS 4405</span> |
				<span class="hyperlink_unavailable" title="Computer Graphics">CS 4406</span> |
				<span class="hyperlink_unavailable" title="Data Mining and Machine Learning">CS 4407</span> |
				<span class="hyperlink_unavailable" title="Artificial Intelligence">CS 4408</span> |
				<span class="hyperlink_unavailable" title="English Composition 2">ENGL 1102</span> |
				<span class="hyperlink_unavailable" title="World Literature">ENGL 1405</span> |
				<span class="hyperlink_unavailable" title="Introduction to Environmental Science">ENVS 1301</span> |
				<a href="/en/coursework/HIST1421/" title="Greek and Roman Civilization">HIST 1421</a> |
				<span class="hyperlink_unavailable" title="College Algebra">MATH 1201</span> |
				<span class="hyperlink_unavailable" title="Calculus">MATH 1211</span> |
				<span class="hyperlink_unavailable" title="Introduction to Statistics">MATH 1280</span> |
				<span class="hyperlink_unavailable" title="Discrete Mathematics">MATH 1302</span> |
				<span class="hyperlink_unavailable" title="Introduction to Philosophy">PHIL 1402</span> |
				<a href="/en/coursework/PHIL1404/" title="Ethics and Social Responsibility">PHIL 1404</a> |
				<a href="/en/coursework/POLS1503/" title="Globalization">POLS 1503</a> |
				<span class="hyperlink_unavailable" title="Introduction to Psychology">PSYC 1504</span> |
				<a href="/en/coursework/UNIV1001/" title="Online Education Strategies">UNIV 1001</a>
			</p>
			<hr/>
			<p>
				<a href="/en/coursework/CS1103/Unit1.java.xhtml" title="Unit1.java">Unit 1</a> |
				<a href="/en/coursework/CS1103/SimpleRandomSentences.java.xhtml" title="SimpleRandomSentences.java">Unit 2</a> |
				<a href="/en/coursework/CS1103/Tape.java.xhtml" title="Tape.java">Unit 3</a> |
				<a href="/en/coursework/CS1103/Debugging.xhtml" title="Debugging">Unit 4</a> |
				<a href="/en/coursework/CS1103/Unit5.java.xhtml" title="Unit5.java">Unit 5</a> |
				<a href="/en/coursework/CS1103/DrawTextPanel.java.xhtml" title="DrawTextPanel.java">Unit 6</a> |
				<a href="/en/coursework/CS1103/Unit7.java.xhtml" title="Unit7.java">Unit 7</a>
			</p>
			<hr/>
		</nav>
		<header>
			<h1>Unit7.java</h1>
			<p>Written in <span title="Programming 2">CS 1103</span> of <a href="http://www.uopeople.edu/">University of the People</a>, finalised on 2017-08-02</p>
		</header>
<h2>Source code</h2>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.Unit7;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 6 submission
 * 
 * This program acts as a basic Web server, processing and responding to HTTP
 * requests.
 * 
 * @author Alex Yst
 */
public class Unit7 {
/**
 * Port 80 should be used, but this is only a demo. Using port 80 requires root
 * access, which isn&apos;t suitable for testing.
 */
	public static int LISTENING_PORT = 8080;
/**
 * Files will be served from ~/www , the &quot;www&quot; subdirectory of a user&apos;s home
 * directory. Again, this isn&apos;t good for a production server, but it&apos;s good for
 * a demo server such as this one. Before we get serious about serving files
 * anyway, we need to implement some basic TLS support.
 */
	public static String rootDirectory = System.getProperty(&quot;user.home&quot;) + &quot;/www&quot;;

	private static class ConnectionThread extends Thread {
		Socket connection;
		ConnectionThread(Socket connection) {
			this.connection = connection;
		}
		public void run() {
			handleConnection(connection);
		}
	}
/**
 * This method processes a client&apos;s request and provides the client with an
 * appropriate responce.
 * 
 * @param connection a Socket object returned by ServerSocket.accept()
 */
	public static void handleConnection(Socket connection) {
		try {
			Scanner input = new Scanner(connection.getInputStream());
			OutputStream outputStream = connection.getOutputStream();
			PrintWriter output = new PrintWriter(outputStream);
			String line = input.nextLine();
			String[] split = line.split(&quot; &quot;);
			File file = new File(rootDirectory + split[1]);
			if(file.isDirectory()) {
				split[1] += &quot;/index.xhtml&quot;;
				file = new File(rootDirectory + split[1]);
			}
			System.out.println(rootDirectory + split[1]);
// Our server is only programmed to handle GET requests. Anything else is not
// implemented, so a 501 NOT IMPLEMENTED status code should be returned.
			if(!split[0].equals(&quot;GET&quot;)) {
				handle501(output, split[0]);
			} else if(!split[2].equals(&quot;HTTP/1.1&quot;) &amp;&amp; !split[2].equals(&quot;HTTP/1.0&quot;)) {
				handle400(output, &quot;Protocol version, &amp;quot;&quot; + split[2] +&quot;&amp;quot;, not understood.&quot;);
			} else if(!split[1].substring(0, 1).equals(&quot;/&quot;)) {
				handle400(output, &quot;The request path must begin with a slash.&quot;);
			} else if(!file.exists()) {
				handle404(output);
			} else if(!file.canRead()) {
				handle403(output);
			} else {
				handle200(output, outputStream, split[1], file);
			}
			input.close();
			output.flush();
			output.close();
		} catch (Exception e) {
			System.out.println(&quot;Error communicating with client:&quot; + e.getMessage());
		} finally {
			try {
				connection.close();
			} catch(Exception e) {
				System.out.println(&quot;Error closing connection:&quot; + e.getMessage());
			}
		}
	}
/**
 * Normal, valid requests are filled by this method.
 * 
 * @param output The PrintWriter to write to
 * @param outputStream The OutputStream to pass to sendFile
 * @param filePath The file&apos;s path
 * @param file The File to send the client
 * @throws IOException This&apos;ll be handled by handleConnection()
 */
	public static void handle200(PrintWriter output, OutputStream outputStream, String filePath, File file) throws IOException {
		System.out.println(&quot;CODE: 200&quot;);
		sendHeaders(output, &quot;200 OK&quot;, (int) file.length(), getMimeType(filePath));
		sendFile(file, outputStream);
	}
/**
 * If a request is invalid, this method handles it.
 * 
 * @param output The PrintWriter to write to
 * @param errorMessage The error message
 */
	public static void handle400(PrintWriter output, String errorMessage) {
		String page = buildErrorPage(&quot;400 Bad Request&quot;, errorMessage);
		sendHeaders(output, &quot;400 Bad Request&quot;, page.length(), &quot;application/xhtml+xml&quot;);
		output.print(page);
		output.flush();
	}
/**
 * When files are not readable by the Web server, the client isn&apos;t allowed
 * access to them. This method responds to such cases.
 * 
 * @param output The PrintWriter to write to
 */
	public static void handle403(PrintWriter output) {
		String page = buildErrorPage(&quot;403 Forbidden&quot;, &quot;You do not have permission to view the requested file on this server.&quot;);
		sendHeaders(output, &quot;403 Forbidden&quot;, page.length(), &quot;application/xhtml+xml&quot;);
		output.print(page);
		output.flush();
	}
/**
 * When files are missing, this method provides a responce.
 * 
 * @param output The PrintWriter to write to
 */
	public static void handle404(PrintWriter output) {
		String page = buildErrorPage(&quot;404 Not Found&quot;, &quot;The requested file could not be found on this server.&quot;);
		sendHeaders(output, &quot;404 Not Found&quot;, page.length(), &quot;application/xhtml+xml&quot;);
		output.print(page);
		output.flush();
	}
/**
 * This simple server only implements the GET method in requests. Anything else
 * is handled by this method.
 * 
 * @param output The PrintWriter to write to
 * @param requestMethod The HTTP request method
 */
	public static void handle501(PrintWriter output, String requestMethod) {
		String page = buildErrorPage(&quot;501 Not Implemented&quot;, &quot;The &quot; + requestMethod + &quot; method is not supported by this server. This server only supports GET requests.&quot;);
		sendHeaders(output, &quot;501 Not Implemented&quot;, page.length(), &quot;application/xhtml+xml&quot;);
		output.print(page);
		output.flush();
	}
/**
 * This method sends the needed headers for responses.
 * 
 * @param output The PrintWriter to write to
 * @param status A status code and message
 * @param contentLength The length of the response body
 * @param contentType The content type of the response
 */
	public static void sendHeaders(PrintWriter output, String status, int contentLength, String contentType) {
		output.print(&quot;HTTP/1.1 &quot; + status + &quot;\r\n&quot;);
		output.print(&quot;Connection: close\r\n&quot;);
		output.print(&quot;Content-Type: &quot; + contentType + &quot;\r\n&quot;);
		output.print(&quot;Content-Length: &quot; + contentLength + &quot;\r\n&quot;);
		output.print(&quot;\r\n&quot;);
		output.flush();
	}
/**
 * This method constructs error pages as needed.
 * 
 * @param title The page &lt;title/&gt; and &lt;h1/&gt; message
 * @param body The message to include in the &lt;body/&gt;&apos;s &lt;p/&gt; element
 * @return The content of a page to send
 */
	public static String buildErrorPage(String title, String body) {
		return &quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;utf-8\&quot;?&gt;\n&quot; +
			&quot;&lt;!--\n&quot; +
			&quot;	Copyright © 2017 Alex Yst &lt;mailto:copyright@y.st&gt;\n&quot; +
			&quot;\n&quot; +
			&quot;	This program is free software: you can redistribute it and/or modify\n&quot; +
			&quot;	it under the terms of the GNU General Public License as published by\n&quot; +
			&quot;	the Free Software Foundation, either version 3 of the License, or\n&quot; +
			&quot;	(at your option) any later version.\n&quot; +
			&quot;\n&quot; +
			&quot;	This program is distributed in the hope that it will be useful,\n&quot; +
			&quot;	but WITHOUT ANY WARRANTY; without even the implied warranty of\n&quot; +
			&quot;	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n&quot; +
			&quot;	GNU General Public License for more details.\n&quot; +
			&quot;\n&quot; +
			&quot;	You should have received a copy of the GNU General Public License\n&quot; +
			&quot;	along with this program. If not, see &lt;http://www.gnu.org./licenses/&gt;.\n&quot; +
			&quot;--&gt;\n&quot; +
			&quot;&lt;!DOCTYPE html&gt;\n&quot; +
			&quot;&lt;html xmlns=\&quot;http://www.w3.org/1999/xhtml\&quot;&gt;\n&quot; +
			&quot;	&lt;head&gt;\n&quot; +
			&quot;		&lt;title&gt;&quot; + title + &quot;&lt;/title&gt;\n&quot; +
			&quot;		&lt;meta name=\&quot;viewport\&quot; content=\&quot;width=device-width\&quot; /&gt;\n&quot; +
			&quot;	&lt;/head&gt;\n&quot; +
			&quot;	&lt;body&gt;\n&quot; +
			&quot;		&lt;h1&gt;&quot; + title + &quot;&lt;/h1&gt;\n&quot; +
			&quot;		&lt;p&gt;\n&quot; +
			&quot;			&quot; + body + &quot;\n&quot; +
			&quot;		&lt;/p&gt;\n&quot; +
			&quot;	&lt;/body&gt;\n&quot; +
			&quot;&lt;/html&gt;\n&quot;;
	}
	public static void main(String[] args) {
		ServerSocket serverSocket;
		try {
			serverSocket = new ServerSocket(LISTENING_PORT);
		}
		catch (Exception e) {
			System.out.println(&quot;Failed to create listening socket.&quot;);
			return;
		}
		System.out.println(&quot;Listening on port &quot; + LISTENING_PORT);
		System.out.println(&quot;Files are being served from &quot; + rootDirectory);
		try {
			while (true) {
				Socket connection = serverSocket.accept();
				System.out.println(&quot;\nConnection from &quot;
						+ connection.getRemoteSocketAddress());
				ConnectionThread thread = new ConnectionThread(connection);
				thread.start();
			}
		}
		catch (Exception e) {
			System.out.println(&quot;Server socket shut down unexpectedly!&quot;);
			System.out.println(&quot;Error: &quot; + e);
			System.out.println(&quot;Exiting.&quot;);
		}
		finally {
			try {
				serverSocket.close();
			} catch(IOException e){
				System.out.println(&quot;Error shutting down server socket.&quot;);
			}
		}
	}
	private static String getMimeType(String fileName) {
		int pos = fileName.lastIndexOf(&apos;.&apos;);
		if (pos &lt; 0)  // no file extension in name
			return &quot;x-application/x-unknown&quot;;
		String ext = fileName.substring(pos+1).toLowerCase();
		if (ext.equals(&quot;txt&quot;)) return &quot;text/plain&quot;;
		else if (ext.equals(&quot;html&quot;)) return &quot;text/html&quot;;
		else if (ext.equals(&quot;htm&quot;)) return &quot;text/html&quot;;
		else if (ext.equals(&quot;css&quot;)) return &quot;text/css&quot;;
		else if (ext.equals(&quot;js&quot;)) return &quot;text/javascript&quot;;
		else if (ext.equals(&quot;java&quot;)) return &quot;text/x-java&quot;;
		else if (ext.equals(&quot;jpeg&quot;)) return &quot;image/jpeg&quot;;
		else if (ext.equals(&quot;jpg&quot;)) return &quot;image/jpeg&quot;;
		else if (ext.equals(&quot;png&quot;)) return &quot;image/png&quot;;
		else if (ext.equals(&quot;gif&quot;)) return &quot;image/gif&quot;;
		else if (ext.equals(&quot;ico&quot;)) return &quot;image/x-icon&quot;;
		else if (ext.equals(&quot;class&quot;)) return &quot;application/java-vm&quot;;
		else if (ext.equals(&quot;jar&quot;)) return &quot;application/java-archive&quot;;
		else if (ext.equals(&quot;zip&quot;)) return &quot;application/zip&quot;;
		else if (ext.equals(&quot;xml&quot;)) return &quot;application/xml&quot;;
		else if (ext.equals(&quot;xhtml&quot;)) return &quot;application/xhtml+xml&quot;;
		else return &quot;x-application/x-unknown&quot;;
// Note:  x-application/x-unknown  is something made up;
// it will probably make the browser offer to save the file.
	}
	private static void sendFile(File file, OutputStream socketOut) throws IOException {
		InputStream in = new BufferedInputStream(new FileInputStream(file));
		OutputStream out = new BufferedOutputStream(socketOut);
		while (true) {
			int x = in.read(); // read one byte from file
			if (x &lt; 0)
				break; // end of file reached
			out.write(x);  // write the byte to the socket
		}
		out.flush();
		in.close();
		out.close();
	}
}</code></pre>
</blockquote>
		<hr/>
		<p>
			Copyright © 2017 Alex Yst;
			You may modify and/or redistribute this document under the terms of the <a rel="license" href="/license/gpl-3.0-standalone.xhtml"><abbr title="GNU&apos;s Not Unix">GNU</abbr> <abbr title="General Public License version Three or later">GPLv3+</abbr></a>.
			If for some reason you would prefer to modify and/or distribute this document under other free copyleft terms, please ask me via email.
			My address is in the source comments near the top of this document.
			This license also applies to embedded content such as images.
			For more information on that, see <a href="/en/a/licensing.xhtml">licensing</a>.
		</p>
		<p>
			<abbr title="World Wide Web Consortium">W3C</abbr> standards are important.
			This document conforms to the <a href="https://validator.w3.org./nu/?doc=https%3A%2F%2Fy.st.%2Fen%2Fcoursework%2FCS1103%2FUnit7.java.xhtml"><abbr title="Extensible Hypertext Markup Language">XHTML</abbr> 5.1</a> specification and uses style sheets that conform to the <a href="http://jigsaw.w3.org./css-validator/validator?uri=https%3A%2F%2Fy.st.%2Fen%2Fcoursework%2FCS1103%2FUnit7.java.xhtml"><abbr title="Cascading Style Sheets">CSS</abbr>3</a> specification.
		</p>
	</body>
</html>

